#!/bin/bash

# Matrix Service Discovery 启动脚本

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查必要的工具
check_dependencies() {
    log_info "检查依赖工具..."

    if ! command -v dotnet &> /dev/null; then
        log_error "dotnet CLI 未安装"
        exit 1
    fi

    if ! command -v docker &> /dev/null; then
        log_warning "Docker 未安装，将跳过容器化启动"
        USE_DOCKER=false
    else
        USE_DOCKER=true
    fi

    log_success "依赖检查完成"
}

# 设置环境变量
setup_environment() {
    log_info "设置环境变量..."

    export ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
    export DOTNET_ENVIRONMENT=$ASPNETCORE_ENVIRONMENT

    log_success "环境设置完成: $ASPNETCORE_ENVIRONMENT"
}

# 检查服务状态
check_services() {
    log_info "检查服务状态..."

    # 检查端口占用
    local ports=("5433" "6380" "5673" "5001")
    local services=("PostgreSQL" "Redis" "RabbitMQ" "ServiceDiscovery")

    for i in "${!ports[@]}"; do
        local port=${ports[$i]}
        local service=${services[$i]}

        if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
            log_warning "$service 端口 $port 已被占用"
        else
            log_info "$service 端口 $port 可用"
        fi
    done
}

# 构建应用
build_application() {
    log_info "构建应用..."

    cd "$(dirname "$0")/../"

    if dotnet build --configuration Release --no-restore; then
        log_success "应用构建成功"
    else
        log_error "应用构建失败"
        exit 1
    fi
}

# 数据库迁移
run_migrations() {
    log_info "运行数据库迁移..."

    cd "$(dirname "$0")/../"

    if dotnet run --project ../MatrixServiceDiscovery.DbMigrator --configuration Release --no-build; then
        log_success "数据库迁移成功"
    else
        log_error "数据库迁移失败"
        exit 1
    fi
}

# 启动基础设施服务
start_infrastructure() {
    if [ "$USE_DOCKER" = true ]; then
        log_info "启动基础设施服务 (Docker)..."

        cd "$(dirname "$0")/../"

        if docker-compose up -d postgres redis rabbitmq; then
            log_success "基础设施服务启动成功"

            # 等待服务就绪
            log_info "等待服务就绪..."
            sleep 10
        else
            log_error "基础设施服务启动失败"
            exit 1
        fi
    else
        log_warning "跳过Docker基础设施启动，请确保 PostgreSQL、Redis、RabbitMQ 已手动启动"
    fi
}

# 启动应用
start_application() {
    log_info "启动 Matrix Service Discovery 应用..."

    cd "$(dirname "$0")/../"

    # 创建必要的目录
    mkdir -p logs data

    if [ "$USE_DOCKER" = true ]; then
        # Docker 模式启动
        log_info "使用 Docker 启动应用..."
        docker-compose up -d matrix-service-discovery

        # 等待应用启动
        log_info "等待应用启动..."
        sleep 15

        # 检查应用健康状态
        local attempts=0
        local max_attempts=30

        while [ $attempts -lt $max_attempts ]; do
            if curl -f http://localhost:5001/health >/dev/null 2>&1; then
                log_success "应用启动成功！"
                break
            fi

            attempts=$((attempts + 1))
            log_info "等待应用启动... ($attempts/$max_attempts)"
            sleep 2
        done

        if [ $attempts -eq $max_attempts ]; then
            log_error "应用启动超时"
            exit 1
        fi
    else
        # 本地模式启动
        log_info "使用本地模式启动应用..."
        dotnet run --configuration Release
    fi
}

# 显示访问信息
show_access_info() {
    log_success "==================================="
    log_success "Matrix Service Discovery 已启动"
    log_success "==================================="
    log_info "应用访问地址:"
    log_info "  - API 地址: http://localhost:5001"
    log_info "  - API 文档: http://localhost:5001/swagger"
    log_info "  - 健康检查: http://localhost:5001/health"
    log_info ""
    log_info "基础设施服务:"
    log_info "  - PostgreSQL: localhost:5433"
    log_info "  - Redis: localhost:6380"
    log_info "  - RabbitMQ: localhost:5673"
    log_info "  - RabbitMQ 管理界面: http://localhost:15673"
    log_info ""
    log_info "监控服务 (如果启用):"
    log_info "  - Prometheus: http://localhost:9091"
    log_info "  - Grafana: http://localhost:3001 (admin/admin123)"
    log_success "==================================="
}

# 清理函数
cleanup() {
    log_info "执行清理操作..."

    if [ "$USE_DOCKER" = true ]; then
        cd "$(dirname "$0")/../"
        docker-compose down
    fi

    log_success "清理完成"
}

# 主函数
main() {
    local command=${1:-"start"}

    case "$command" in
        "start")
            log_info "启动 Matrix Service Discovery..."
            check_dependencies
            setup_environment
            check_services
            start_infrastructure
            run_migrations
            start_application
            show_access_info
            ;;
        "build")
            log_info "仅构建应用..."
            build_application
            ;;
        "migrate")
            log_info "仅运行数据库迁移..."
            run_migrations
            ;;
        "docker")
            log_info "Docker 模式启动..."
            start_infrastructure
            start_application
            show_access_info
            ;;
        "clean")
            log_info "清理..."
            cleanup
            ;;
        "help"|"-h"|"--help")
            echo "Matrix Service Discovery 启动脚本"
            echo ""
            echo "用法: $0 [命令]"
            echo ""
            echo "命令:"
            echo "  start    - 完整启动应用 (默认)"
            echo "  build    - 仅构建应用"
            echo "  migrate - 仅运行数据库迁移"
            echo "  docker   - Docker 模式启动"
            echo "  clean    - 清理资源"
            echo "  help     - 显示帮助信息"
            ;;
        *)
            log_error "未知命令: $command"
            log_info "使用 '$0 help' 查看帮助信息"
            exit 1
            ;;
    esac
}

# 捕获退出信号
trap cleanup EXIT

# 执行主函数
main "$@"